﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using CloudShot.Entities;
using CloudShot.Interfaces;
using CloudShot.Properties;
using CloudShot.States;
using CloudShot.Utils;

namespace CloudShot
{
	internal partial class ShotForm : Form
	{
		private readonly string _storageName;
		private readonly Color _fillColor;
		private IShotState _state;//TOSO: наверно стоит вообще избавиться от стейтов, подумать могут ли они вообще понадобится

		public CaptureInfo CaptureInfo { get; private set; }

		public ShotForm(string storageName, Color fillColor)
		{
			_storageName = storageName;
			_fillColor = fillColor;
			InitializeComponent();
			Icon = Resources.applicationIcon;
		}

		private void ShotForm_Load(object sender, EventArgs e)
		{
			_state = new ShotState(this, _storageName, _fillColor);
			User32.SetForegroundWindow(Handle);

#if DEBUG
			TopMost = false;
#endif
		}

		private void ShotForm_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left)
			{
				_state.End();
				DialogResult = DialogResult.Cancel;
				Close();
				return;
			}
			_state.Start(e.Location);
		}

		private void ShotForm_MouseUp(object sender, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left)
			{
				DialogResult = DialogResult.Cancel;
				Close();
				return;
			}

			CaptureInfo = _state.End();
			_state = null;

			DialogResult = DialogResult.OK;
			Close();
		}

		private Point _lastLocation;

		protected override CreateParams CreateParams
		{
			get
			{
				CreateParams cp = base.CreateParams;
				cp.ExStyle |= 0x02000000;//ClipChildren
				return cp;
			}
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			//base.OnMouseMove(e);
			if (_lastLocation == e.Location)
				return;

			_lastLocation = e.Location;
			_state.Update(e.Location);

			Invalidate();//marks form to be redrawn
			//Update();//immediately redraws form - don't call this method here, it's very slow and unneccessary			
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			//base.OnPaint(e);
			//Stopwatch myStopwatch = new Stopwatch();

			//myStopwatch.Start();
			e.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
			e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
			e.Graphics.InterpolationMode = InterpolationMode.Low;
			e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
			e.Graphics.CompositingMode = CompositingMode.SourceOver;

			_state.Paint(e.Graphics);

			//myStopwatch.Stop();

			//// Get the elapsed time as a TimeSpan value.
			//TimeSpan ts = myStopwatch.Elapsed;

			//// Format and display the TimeSpan value.
			//string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
			//Trace.WriteLine(elapsedTime, "RunTime");
		}

		private void ShotForm_Deactivate(object sender, EventArgs e)
		{
			Close();
		}

		private void ShotForm_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Escape)
			{
				_state.End();
				DialogResult = DialogResult.Cancel;
				Close();
			}
		}
	}
}